/**
 * 
 */
package furniture.items3d.bounds;

import javax.vecmath.Vector3d;

import static java.lang.Math.*; 

/**
 * This class determines a cuboid bound in the 3D context. It stores
 * min and max coordinates in millimetres.
 * @author Grill Balazs (balage.g@gmail.com)
 *
 */
public class Bounds3d {

	public final Vector3d min;
	
	public final Vector3d max;
	
	/*protected Bounds3d(Vector3d min, Vector3d max){
		this.min=min;
		this.max=max;
	}*/
	
	/**
	 * expand the bounds to be sqare
	 */
	public Bounds3d normalize(){
		Vector3d min = new Vector3d(this.min);
		Vector3d max = new Vector3d(this.max);
		Vector3d size = new Vector3d(max);
		size.sub(min);
		
		double msize = max(size.x,max(size.y,size.z));
		
		Vector3d expand = new Vector3d(msize-size.x,msize-size.y,msize-size.z);
		expand.scale(1.0/2.0);
		
		min.sub(expand);
		max.add(expand);
		
		return new Bounds3d(min,max);
	}
	
	/**
	 * This constructor is used to determine the bounding cuboid
	 * which includes all of the given bounds.
	 * @param bounds
	 */
	public Bounds3d(Bounds3d... bounds){
		if (bounds.length == 0) throw new NullPointerException();
		Vector3d min = bounds[0].min;
		Vector3d max = bounds[0].max;
		for(int i = 1; i<bounds.length;i++){
			min = vmin(min,bounds[i].min);
			max = vmax(max,bounds[i].max);
		}
		this.max = max;
		this.min = min;
	}
	
	/**
	 * Create a bounding cuboid, which includes all the given vectors
	 * @param vectors
	 */
	public Bounds3d(Vector3d... vectors){
		if (vectors.length == 0) throw new NullPointerException();
		Vector3d min = vectors[0];
		Vector3d max = vectors[0];
		for(int i = 1;i<vectors.length;i++){
			min = vmin(min,vectors[i]);
			max = vmax(max,vectors[i]);
		}
		this.max = max;
		this.min = min;
	}
	
	/**
	 * @param v1
	 * @param v2
	 * @return
	 */
	public static Vector3d vmin(Vector3d v1, Vector3d v2){
		return new Vector3d(min(v1.x,v2.x),min(v1.y,v2.y),min(v1.z,v2.z));
	}
	
	/**
	 * @param v1
	 * @param v2
	 * @return
	 */
	public static Vector3d vmax(Vector3d v1, Vector3d v2){
		return new Vector3d(max(v1.x,v2.x),max(v1.y,v2.y),max(v1.z,v2.z));
	}
	
}

